home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume22 / tpipe < prev    next >
Encoding:
Internet Message Format  |  1990-06-07  |  8.9 KB

  1. Subject:  v22i011:  A "tee" that feeds into pipes.
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: eb657f50 8b3e9993 537c1e87 2f5979a0
  5.  
  6. Submitted-by: David B Rosen <rosen@bucasb.bu.edu>
  7. Posting-number: Volume 22, Issue 11
  8. Archive-name: tpipe
  9.  
  10. tpipe is a simple utility program that can be used to split a unix
  11. pipeline into two pipelines. That is, the output of one pipeline can
  12. be replicated and supplied as the input to two other pipelines
  13. executing simultaneously.
  14.  
  15. For example
  16.     cmd1 <infile | tpipe "cmd2 | cmd3 >outfile" | cmd4 
  17. will look like this diagramatically:
  18.              --> cmd2 --> cmd3 --> outfile
  19.                /
  20.     infile  --> cmd1 -<
  21.                \\
  22.              --> cmd4 -->  (standard output)
  23.  
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then unpack
  26. # it by saving it into a file and typing "sh file".  To overwrite existing
  27. # files, type "sh file -c".  You can also feed this as standard input via
  28. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  29. # will see the following message at the end:
  30. #        "End of shell archive."
  31. # Contents:  Makefile README tpipe.1 tpipe.c
  32. # Wrapped by rsalz@papaya.bbn.com on Thu May  3 16:40:10 1990
  33. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  34. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  35.   echo shar: Will not clobber existing file \"'Makefile'\"
  36. else
  37. echo shar: Extracting \"'Makefile'\" \(107 characters\)
  38. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  39. XCC =        cc
  40. XCFLAGS =    -O
  41. XTPIPE =        tpipe
  42. XCFILES =    tpipe.c
  43. X
  44. X$(TPIPE): $(CFILES)
  45. X    $(CC) $(CFLAGS) $(CFILES) -o $@
  46. END_OF_FILE
  47. if test 107 -ne `wc -c <'Makefile'`; then
  48.     echo shar: \"'Makefile'\" unpacked with wrong size!
  49. fi
  50. # end of 'Makefile'
  51. fi
  52. if test -f 'README' -a "${1}" != "-c" ; then 
  53.   echo shar: Will not clobber existing file \"'README'\"
  54. else
  55. echo shar: Extracting \"'README'\" \(2118 characters\)
  56. sed "s/^X//" >'README' <<'END_OF_FILE'
  57. X-------------------------------------------------------------
  58. Xtpipe --  replicate standard output to an additional pipeline
  59. X              version 1.02    6 Mar. 1990
  60. X-------------------------------------------------------------
  61. X
  62. Xtpipe is a simple utility program that can be used to split a unix
  63. Xpipeline into two pipelines. That is, the output of one pipeline can
  64. Xbe replicated and supplied as the input to two other pipelines
  65. Xexecuting simultaneously.
  66. X
  67. XLike tee(1), tpipe transcribes its standard input to its standard
  68. Xoutput. But where tee(1) writes an additional copy of its input to a
  69. Xfile, tpipe writes the additional copy to the input of another
  70. Xpipeline, which is specified as the argument to tpipe. In a typical
  71. Xuse, this pipeline will eventually write to a file. The standard
  72. Xoutput of tpipe is typically piped into another pipeline, whose output
  73. X(if any) may go to the user's terminal or anywhere at all.
  74. X
  75. XI wrote tpipe because I was processing image files (using pbmplus),
  76. Xand I wanted to apply more than one pipeline to the same input file,
  77. Xbut the early parts of the pipeline were the same. I did not want to
  78. Xhave to execute the early parts multiple times. I did not have enough
  79. Xdisk space to write what would have been a huge intermediate file.
  80. XFrankly, I did not know about teeing to named pipes, but anyway it's
  81. Xnice not to have to bother with them or worry about name conflicts,
  82. Xespecially if you have more than one job wanting to do this at the
  83. Xsame time...
  84. X
  85. XSee the manual page for tpipe(1) for information about its use,
  86. Xincluding an artificial example. 
  87. X
  88. XThis distribution contains four files:
  89. X  Readme (this is it)
  90. X  Makefile (it is trivial)
  91. X  tpipe.1  (the manual page)
  92. X  tpipe.c  (the code!)
  93. X
  94. XTo read the manual page, just `nroff -man tpipe.1'.
  95. X
  96. XTo compile tpipe, just `make'. Put tpipe.1 in the man1/ directory in
  97. Xyour MANPATH or the system man path.
  98. X
  99. X--
  100. XDavid B Rosen, Cognitive & Neural Systems                  rosen@bucasb.bu.edu
  101. XCenter for Adaptive Systems                 rosen%bucasb@{buacca,bu-it}.bu.edu
  102. XBoston University              {mit-eddie,harvard,uunet}!bu.edu!thalamus!rosen
  103. END_OF_FILE
  104. if test 2118 -ne `wc -c <'README'`; then
  105.     echo shar: \"'README'\" unpacked with wrong size!
  106. fi
  107. # end of 'README'
  108. fi
  109. if test -f 'tpipe.1' -a "${1}" != "-c" ; then 
  110.   echo shar: Will not clobber existing file \"'tpipe.1'\"
  111. else
  112. echo shar: Extracting \"'tpipe.1'\" \(2465 characters\)
  113. sed "s/^X//" >'tpipe.1' <<'END_OF_FILE'
  114. X.TH TPIPE 1  "29 January 1990"
  115. X.\" @(#)tpipe.1 1.0 90/01/29; David B Rosen (rosen@bucasb.bu.edu)
  116. X.SH NAME
  117. Xtpipe \- replicate the standard output into an additional pipeline
  118. Xthat is run in a subshell
  119. X.SH SYNOPSIS
  120. X.B tpipe
  121. X[
  122. X.I pipeline
  123. X]
  124. X.IX  "tpipe command"  ""  "\fLtpipe\fP \(em copy standard output to many pipelines"
  125. X.IX  "copy" "standard output to many pipelines \(em \fLtpipe\fP"
  126. X.IX  "standard output"  "copy to many pipelines"  ""  "copy to many pipelines \(em \fLtpipe\fP"
  127. X.IX  pipelines  "copy standard output to many"  ""  "copy standard output to many \(em \fLtpipe\fP"
  128. X.SH DESCRIPTION
  129. X.B tpipe
  130. Xtranscribes the standard input to the
  131. Xstandard output and simultaneously writes an additional copy to
  132. Xa specified
  133. X.IR pipeline .
  134. X.PP
  135. Xtpipe is similar to tee(1) except that tpipe writes the duplicate copy
  136. Xof its standard input to a command or pipeline instead of a file. This
  137. Xcan help you avoid re-executing earlier commands in the pipeline,
  138. Xwriting temporary files, or resorting to the use of named pipes.
  139. X.PP
  140. XThe specified
  141. X.IR pipeline
  142. Xis always executed in a subshell by sh(1), regardless of your current
  143. Xshell.  If a non-empty string is supplied as the argument, it must be 
  144. Xa valid pipeline or command for sh(1). Normally, you will want to enclose
  145. Xthe
  146. X.IR pipeline
  147. Xargument in quotes ('' or "").  The type of quotes you choose
  148. Xwill affect variable substitution by your shell (see the man page 
  149. Xfor your shell, such as csh(1), for details).
  150. X.PP
  151. XIf the subshell pipeline writes to its standard output, this output
  152. Xwill go to the standard output of tpipe, where it will be interspersed
  153. Xin an unpredictable way with the other copy of standard input.
  154. XNormally, this is not what you want. Instead, you would typically
  155. Xspecify a subshell
  156. X.IR pipeline 
  157. Xwhose output is redirected to a file (as in the example
  158. Xbelow) or has some other effect.
  159. X.SH EXAMPLE
  160. X.IP
  161. X% cmd1 <infile | tpipe "cmd2 | cmd3 >outfile" | cmd4 
  162. X.PP
  163. Xwhich has the effect of running the output of command cmd1
  164. Xsimultaneously through two pipelines, "cmd2 | cmd3 >outfile" and cmd4.
  165. XDiagramatically, in this example (this will look wrong with
  166. Xa variable-spaced font):
  167. X
  168. X.nf
  169. X                     --> cmd2 --> cmd3 --> outfile
  170. X                   /
  171. Xinfile  --> cmd1 -<
  172. X                   \\
  173. X                     --> cmd4 -->  (standard output)
  174. X.fi
  175. X.SH SEE ALSO
  176. X.BR tee (1),
  177. X.BR sh (1),
  178. X.BR cat (1)
  179. X
  180. X.SH AUTHOR
  181. XDavid B Rosen
  182. X.PP
  183. XTHIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT EXPRESS OR IMPLIED WARRANTY.
  184. END_OF_FILE
  185. if test 2465 -ne `wc -c <'tpipe.1'`; then
  186.     echo shar: \"'tpipe.1'\" unpacked with wrong size!
  187. fi
  188. # end of 'tpipe.1'
  189. fi
  190. if test -f 'tpipe.c' -a "${1}" != "-c" ; then 
  191.   echo shar: Will not clobber existing file \"'tpipe.c'\"
  192. else
  193. echo shar: Extracting \"'tpipe.c'\" \(1603 characters\)
  194. sed "s/^X//" >'tpipe.c' <<'END_OF_FILE'
  195. X/* tpipe.c -- tee a pipeline into two pipelines. Like tee(1) but 
  196. X   argument is a command or pipeline rather than a file.
  197. X
  198. X   See the man page tpipe(1) supplied with this software.
  199. X
  200. X   This version uses the unix system calls popen(3), read(2), and
  201. X   write(2).  It uses write(2) to write directly to the fileno() of
  202. X   of the file pointer stream returned by popen.
  203. X
  204. X   I've tried it out under BSD, System V, and an older version of unix,
  205. X   but:
  206. X
  207. X   THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT EXPRESS OR IMPLIED 
  208. X   WARRANTY.
  209. X
  210. X   Version 1.02 (4 Mar 1989) (Use fileno())
  211. X
  212. X--
  213. XDavid B Rosen, Cognitive & Neural Systems                  rosen@bucasb.bu.edu
  214. XCenter for Adaptive Systems                 rosen%bucasb@{buacca,bu-it}.bu.edu
  215. XBoston University              {mit-eddie,harvard,uunet}!bu.edu!thalamus!rosen
  216. X
  217. X*/
  218. X
  219. X#include <stdio.h>
  220. X
  221. X/*#define NOHACK*/
  222. X
  223. X#ifndef BUFSIZ
  224. X#define BUFSIZ 2048
  225. X#endif /*BUFSIZ*/
  226. X
  227. Xint main(argc, argv)
  228. X     int argc;
  229. X     char *argv[];
  230. X{
  231. X  char buf[BUFSIZ];
  232. X  register FILE *subpipeline = NULL;
  233. X  register unsigned n;
  234. X
  235. X  if (argc == 2){
  236. X    if (*argv[1]) {
  237. X      if ((subpipeline = popen(argv[1],"w")) == NULL) {
  238. X    fprintf(stderr, "%s: can't create subpipeline %s\n", argv[0], argv[1]);
  239. X    exit(1);
  240. X      }
  241. X    }
  242. X  } else if (argc > 2) {
  243. X    fprintf(stderr, "usage: %s [pipeline]\n", argv[0]);
  244. X    exit(2);
  245. X  }
  246. X
  247. X  while ((n = read(0, buf, BUFSIZ)) > 0) {
  248. X    write(1, buf, n); /* write to standard output */
  249. X    if (subpipeline) {  /* write to subpipeline: */
  250. X      write((int)fileno(subpipeline), buf, n);
  251. X    }
  252. X  }
  253. X
  254. X  if (subpipeline) pclose(subpipeline);
  255. X  return 0;
  256. X}
  257. END_OF_FILE
  258. if test 1603 -ne `wc -c <'tpipe.c'`; then
  259.     echo shar: \"'tpipe.c'\" unpacked with wrong size!
  260. fi
  261. # end of 'tpipe.c'
  262. fi
  263. echo shar: End of shell archive.
  264. exit 0
  265. exit 0 # Just in case...
  266.